<!--
 * @Author: zhangyonggui
 * @Date: 2023-10-25 15:20:50
 * @LastEditors: zhangyonggui
 * @LastEditTime: 2024-01-20 10:55:36
 * @Descripttion: 下发任务
-->
<template>
  <el-dialog
    title="创建任务计划"
    :visible.sync="visible"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    :modal-append-to-body="false"
    width="70%"
    top="5vh"
  >
    <div class="dialog-body">
      <el-form
        ref="formRef"
        :model="form"
        :rules="rules"
        class="strategyForm"
        label-width="145px"
      >
        <div class="card-box">
          <div class="card-title">
            <img src="@/static/images/icon/bar.png" alt="" />
            <span>计划策略配置</span>
          </div>
          <div class="card-content">
            <el-form-item label="任务策略：" prop="strategyId">
              <el-select
                v-model="form.strategyId"
                size="small"
                filterable
                placeholder="请选择"
                @change="strategyChange"
              >
                <el-option
                  v-for="item in strategOptions"
                  :key="item.id"
                  :label="item.strategyName"
                  :value="item.id"
                >
                </el-option>
              </el-select>
              <div class="strategy-name-box">
                <div
                  class="strategy-item"
                  v-for="(item, index) in form.strategyNodeInputList"
                  :key="index"
                >
                  <div class="strategy-title">{{ item.nodeName }}</div>
                  <el-form-item
                    class="strategy-content"
                    v-for="(item1, index1) in item.inputPreConfig"
                    :label="item1.name"
                    :key="index1"
                    prop=""
                    :rules="{}"
                  >
                    <el-input
                      type="textarea"
                      :rows="5"
                      disabled
                      v-model="item1.value"
                      size="small"
                    />
                  </el-form-item>
                </div>
              </div>
            </el-form-item>
          </div>

          <WorkflowGraph
            ref="graph"
            :graphData="graphData"
            :saveType="saveType"
          ></WorkflowGraph>
        </div>
        <div class="card-box">
          <div class="card-title">
            <img src="@/static/images/icon/bar.png" alt="" />
            <span>计划周期性配置</span>
          </div>
          <div class="card-content">
            <el-form-item label="任务类型：" prop="triggerType">
              <el-radio-group v-model="form.triggerType">
                <el-radio :label="0">单次任务</el-radio>
                <el-radio :label="1">周期任务</el-radio>
              </el-radio-group>
            </el-form-item>
            <el-form-item
              v-if="form.triggerType === 1"
              label="重复周期"
              prop="cycle"
            >
              <el-radio-group v-model="form.cycle">
                <el-radio :label="1">周</el-radio>
                <el-radio :label="2">月</el-radio>
              </el-radio-group>
              <div class="week-box" v-if="form.cycle === 1">
                <el-select
                  v-model="form.cycleInterval"
                  size="small"
                  placeholder="请选择"
                  style="width: 320px"
                >
                  <el-option
                    v-for="item in weekOptions"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  >
                  </el-option>
                </el-select>
                <el-time-picker
                  v-model="form.cycleTime"
                  :append-to-body="false"
                  :picker-options="{
                    selectableRange: '18:30:00 - 20:30:00',
                  }"
                  placeholder="任意时间点"
                  value-format="HH:mm:ss"
                  @change="cycleTimeChange"
                  style="width: 320px"
                >
                </el-time-picker>
              </div>
              <div class="month-box" v-if="form.cycle === 2">
                <el-select
                  v-model="form.cycleInterval"
                  size="small"
                  placeholder="请选择"
                  style="width: 320px"
                >
                  <el-option
                    v-for="item in monthOptions"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  >
                  </el-option>
                </el-select>
                <el-time-picker
                  v-model="form.cycleTime"
                  :append-to-body="false"
                  :picker-options="{
                    selectableRange: '18:30:00 - 20:30:00',
                  }"
                  placeholder="任意时间点"
                  value-format="HH:mm:ss"
                  @change="cycleTimeChange"
                  style="width: 320px"
                >
                </el-time-picker>
              </div>
            </el-form-item>
            <el-form-item label="执行时间范围：">
              <el-time-picker
                size="small"
                is-range
                v-model="form.time"
                range-separator="至"
                start-placeholder="开始时间"
                end-placeholder="结束时间"
                placeholder="选择时间范围"
                :append-to-body="false"
                value-format="HH:mm:ss"
                @change="timeChange"
              >
              </el-time-picker>
            </el-form-item>
            <el-form-item label="任务超时：">
              <el-input
                v-model="form.taskTimeout"
                placeholder="请输入时间"
                maxlength="32"
                size="small"
              >
                <template #append>小时</template>
              </el-input>
            </el-form-item>
          </div>
        </div>
        <div class="card-box">
          <div class="card-title">
            <img src="@/static/images/icon/bar.png" alt="" />
            <span>数据标记</span>
          </div>
          <div class="card-content">
            <el-form-item label="数据标记：" prop="">
              <el-switch
                v-model="form.isTaskDataTag"
                :active-value="0"
                :inactive-value="1"
              >
              </el-switch>
              <el-tooltip
                class="item"
                effect="dark"
                content="对任务计划执行中任务模块的结果进行数据标记"
                placement="right"
              >
                <i class="vulfont vul-kongxinwenhao"></i>
              </el-tooltip>
            </el-form-item>
            <table class="tag-table">
              <tbody>
                <tr v-for="(item, index) in form.taskTag" :key="index">
                  <td>{{ item.name }}</td>
                  <td>
                    <div
                      class="tag-box"
                      v-for="(item1, index1) in item.tags"
                      :key="index1"
                    >
                      <span>{{ item1.name }}</span>
                      <i
                        class="tag-close el-icon-close"
                        @click="handleClose(item1, index)"
                      ></i>
                    </div>
                    <template>
                      <el-input
                        class="input-new-tag"
                        v-if="item.inputVisible"
                        v-model="item.inputValue"
                        :ref="`saveTagInput${index}`"
                        size="small"
                        @keyup.enter.native="$event.target.blur()"
                        @blur="handleInputConfirm(item, index)"
                      >
                      </el-input>
                      <div
                        v-else
                        class="new-tag"
                        @click="showInput(item, index)"
                      >
                        + 新增
                      </div>
                    </template>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </el-form>
    </div>
    <span slot="footer" class="dialog-footer">
      <el-button size="small" @click="cancel">取 消</el-button>
      <el-button type="primary" size="small" :loading="loading" @click="confirm"
        >确 定</el-button
      >
    </span>
  </el-dialog>
</template>

<script lang="ts" setup>
import {
  defineProps,
  defineEmits,
  ref,
  reactive,
  watch,
  onMounted,
  nextTick,
} from 'vue';
import { ElMessage } from 'element-plus';
import { useStore } from 'vuex';
import tools from '@/plugins/common';
const store = useStore();
const emit = defineEmits(['update:isShow', 'update']);
const saveTagInput = ref<any>([]);
const props = defineProps({
  isShow: {
    type: Boolean,
    default: false,
  },
  assetIds: {
    type: Array,
    default: () => [],
  },
  category: {
    type: String,
    default: '',
  },
  title: {
    type: String,
    default: '确认',
  },
  searchData: {
    type: Object,
    default: () => {
      return {};
    },
  },
  selectType: {
    type: Number,
    default: 0,
  },
});
const visible = ref(props.isShow);
const form = reactive<any>({
  strategyName: '', // 策略名称
  strategyId: '', // 策略id
  triggerType: 0, // 任务类型：
  cycle: 1, //重复周期
  cycleInterval: '', // 周期间隔
  cycleTime: '', // 周期执行时间 HH:mm:ss
  time: '', //执行时间范围
  scopeStartTime: '', // 执行范围-开始时间 HH:mm:ss
  scopeEndTime: '', //执行范围-结束时间 HH:mm:ss
  taskTimeout: '', //任务超时：
  strategyNodeInputList: [],
  strategyConfig: [],
  isTaskDataTag: 0,
  taskTag: [],

  holdingRatio: props.searchData.holdingRatio,
  assetIds: props.assetIds,
  selectType: props.selectType,
  assetType: props.searchData.searchType,
  condition: props.searchData.searchCondition,
  orderCondition: props.searchData.orderCondition,
  pageSize: 1000,
});
const formRef = ref<any>(null);
const strategOptions = ref<any>([]);
//周
const weekOptions = ref([
  {
    label: '周一',
    value: '1',
  },
  {
    label: '周二',
    value: '2',
  },
  {
    label: '周三',
    value: '3',
  },
  {
    label: '周四',
    value: '4',
  },
  {
    label: '周五',
    value: '5',
  },
  {
    label: '周六',
    value: '6',
  },
  {
    label: '周日',
    value: '7',
  },
]);
//月
const monthOptions = ref<any>([]);
const graphData = ref(); //画布数据
const saveType = ref('plan'); // 画布保存类型
const graph = ref<any>(null);
const rules = reactive({
  strategyId: [
    { required: true, message: '请选择任务策略', trigger: 'change' },
  ],
  triggerType: [
    { required: true, message: '请选择任务类型', trigger: 'change' },
  ],
  cycle: [{ required: true, message: '请选择重复周期', trigger: 'change' }],
  time: [
    {
      required: true,
      message: '请选择时间',
      trigger: 'change',
    },
  ],
  taskTimeout: [
    {
      required: true,
      message: '请输入时间',
      trigger: 'blur',
    },
  ],
});
const loading = ref(false);
watch(
  () => visible.value,
  (newValue, oldValue) => {
    emit('update:isShow', newValue);
  },
);
onMounted(() => {
  getStrategyList();
  setMonthOptions();
});
const cancel = () => {
  visible.value = false;
};
const handleData = (arr) => {
  const newArr = arr;
  for (let i = 0; i < newArr.length; i++) {
    if (newArr[i].shape === 'dag-node') {
      let formatArr = newArr[i].data.engine.dynamicFieldAndValue;
      newArr[i].data.engine.dynamicFieldAndValue = tools.convertDataFormat(
        formatArr,
        'save',
      );
    }
  }
  return newArr;
};
const setMonthOptions = () => {
  for (let i = 1; i < 32; i++) {
    monthOptions.value.push({
      label: `${i}号`,
      value: `${i}`,
    });
  }
};
const timeChange = (val) => {
  if (val) {
    form.scopeStartTime = val[0];
    form.scopeEndTime = val[1];
  } else {
    form.scopeStartTime = '';
    form.scopeEndTime = '';
  }
};
const cycleTimeChange = (val) => {
  if (val) {
    form.cycleTime = val;
  } else {
    form.cycleTime = '';
  }
};
// 策略配置选择
const strategyChange = (val) => {
  form.strategyId = val;
  getStrategyInput(val);
  getStrategyDetail(val);
  getTagList(val);
  for (let i = 0; i < strategOptions.value.length; i++) {
    if (strategOptions.value[i].id === val) {
      form.strategyName = strategOptions.value[i].strategyName;
    }
  }
};
// 获取计划策略配置
const getStrategyList = async () => {
  const {
    code,
    data = [],
    message,
  } = await store.dispatch('expose/getStrategyList');
  if (code !== 0) {
    ElMessage.error(message);
    return;
  }
  strategOptions.value = data;
};
const getStrategyInput = async (strategyId) => {
  const params = {
    assetIds: props.assetIds,
    selectType: props.selectType,
    assetType: props.searchData.searchType,
    workflowId: strategyId,
    condition: props.searchData.searchCondition,
    orderCondition: props.searchData.orderCondition,
    pageSize: 1000,
  };

  const { code, data = [] } = await store.dispatch(
    'expose/getStrategyInput',
    params,
  );
  if (code !== 0) {
    return;
  }
  form.strategyNodeInputList = data;
};
// 获取画布数据
const getStrategyDetail = async (strategyId) => {
  const { code, data = {} } = await store.dispatch(
    'expose/getStrategyDetail',
    strategyId,
  );
  if (code !== 0) {
    return;
  }

  if (data.strategyConfig) {
    graphData.value = JSON.parse(data.strategyConfig);
  }
};
// 删除
const handleClose = (item1, index) => {
  form.taskTag[index].tags.splice(form.taskTag[index].tags.indexOf(item1), 1);
};
const showInput = (item, index) => {
  // this.$set(form.taskTag, index, {
  //   ...item,
  //   inputVisible: true,
  // })
  form.taskTag[index].inputVisible = true;
  nextTick(() => {
    if (saveTagInput.value?.[index]) {
      saveTagInput.value[index].$refs.input.focus();
    }
  });
};
const handleInputConfirm = (item, index) => {
  if (item.inputValue) {
    form.taskTag[index].tags.push({
      name: item.inputValue,
    });
    form.taskTag[index].inputVisible = false;
    form.taskTag[index].inputValue = '';
  }
};
const getTagList = async (strategyId) => {
  const {
    code,
    data = [],
    message,
  } = await store.dispatch('expose/getTagList', strategyId);
  if (code !== 0) {
    ElMessage.error(message);
    return;
  }
  form.taskTag = data;

  for (let i = 0; i < form.taskTag.length; i++) {
    form.taskTag[i].inputVisible = false;
    form.taskTag[i].inputValue = '';
  }
};
const confirm = async () => {
  formRef.value.validate(async (valid) => {
    if (valid) {
      let list = form.strategyNodeInputList;
      let flagArr: any = [];
      for (let i = 0; i < list.length; i++) {
        let flag = false;
        for (let j = 0; j < list[i].inputPreConfig.length; j++) {
          let el = list[i].inputPreConfig[j].value;
          if (el) {
            flag = true;
            break;
          }
        }
        flagArr.push(flag);
      }

      let flagVal = flagArr.every((v) => v == true);
      if (!flagVal) {
        ElMessage.error('每个任务策略下的引擎至少有一条数据');
        return;
      }

      let strategyConfig = [];
      if (graph.value) {
        strategyConfig = graph.value.getGraphData();
      }
      form.strategyConfig = handleData(strategyConfig);

      loading.value = true;
      const { code, data, message } = await store.dispatch(
        'expose/taskDistribute',
        form,
      );
      loading.value = false;
      if (code !== 0) {
        ElMessage.error(message);
        return;
      }
      cancel();
      ElMessage.success('下发成功');
      emit('update');
    } else {
      return false;
    }
  });
};
</script>
<style lang="scss" scoped>
.condition-wrap {
  div {
    margin: 10px 0px;
  }
}

// 表单form
.strategyForm {
  .card-box {
    .card-title {
      font-size: 16px;
      // line-height: 24px;
      letter-spacing: 0px;
      color: rgba(255, 255, 255, 0.9);
      // margin-bottom: 24px;
      padding: 24px 24px;

      img {
        width: 14px;
        height: 14px;
        margin-right: 8px;
      }
    }

    .card-content {
      max-width: 930px;
      min-width: 500px;

      .strategy-name-box {
        .strategy-item {
          .strategy-title {
            font-family: PingFang SC;
            font-size: 14px;
            line-height: 22px;
            color: rgba(255, 255, 255, 0.9);
            margin-top: 10px;
            margin-bottom: 8px;
          }

          .strategy-content {
            ::v-deep .el-form-item__label {
              float: none;
            }

            ::v-deep .el-form-item__content {
              margin-left: 0px !important;
            }
          }

          .el-form-item {
            margin-bottom: 25px;
            // display: flex;
            // align-items: center;
            // justify-content: center;
          }
        }
      }
    }
  }

  .el-form-item__label {
    font-family: PingFang SC;
    font-size: 14px;
    font-weight: normal;
    // text-align: right;
    letter-spacing: 0px;
    color: rgba(255, 255, 255, 0.7);
    // width: 145px !important;
  }

  .el-select,
  .el-date-editor {
    width: 100%;
  }
}

.tag-table {
  border-collapse: collapse;
  width: 100%;
  margin-left: 70px;

  tr {
    border: 1px solid rgba(255, 255, 255, 0.1);
  }

  td {
    // height: 46px;
    &:first-child {
      background: rgba(255, 255, 255, 0.05);
      // padding-left: 32px;
      // width: 40%;
      max-width: 200px;
      min-width: 100px;
      padding: 5px;
    }

    &:last-child {
      display: flex;
      align-items: center;
      flex-wrap: wrap;
      // justify-content: center;
      padding: 5px;
    }

    .tag-box {
      margin: 5px 8px;
      height: 24px;
      display: flex;
      align-items: center;
      padding: 2px 12px;
      background: rgba(210, 222, 235, 0.1);
      box-sizing: border-box;
      border: 0.5px solid rgba(210, 222, 235, 0.5);
      font-family: PingFang SC;
      font-size: 14px;
      font-weight: normal;
      color: rgba(255, 255, 255, 0.9);
      border-radius: 4px;

      .tag-close {
        cursor: pointer;
        margin-left: 5px;
      }
    }

    .input-new-tag {
      min-width: 100px;
      max-width: 150px;
      // height: 24px;
    }

    ::v-deep .el-input--small .el-input__inner {
      height: 24px;
      line-height: 24px;
    }

    .new-tag {
      width: 66px;
      height: 24px;
      border-radius: 4px;
      box-sizing: border-box;
      border: 0.5px dashed #0289f7;
      font-size: 14px;
      font-weight: normal;
      line-height: 20px;
      color: #0289f7;
      cursor: pointer;
      text-align: center;
      margin: 0px 8px;
    }
  }
}
</style>
